package springboard.webapp.controller;

import common.exception.BadRequestException;
import common.exception.ConflictException;
import common.exception.InternalServerException;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;

@Slf4j
@RestController
@RequestMapping("/api")
public class UploadController {

    @Value("${springboard.file-directory:files}")
    String fileDirectory;

    @Value("${springboard.file-context-path:/files}")
    String fileContextPath;

    @ApiOperation("上传文件")
    @PostMapping(value = "/upload/{path}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @ResponseBody
    public String upload(@ApiParam("文件保存路径，可包含指定保存的文件名（以是否包含与上传文件相同的扩展名来判断）") @PathVariable("path") String path,
                         @ApiParam("Multipart文件内容") @RequestPart("file") MultipartFile file,
                         @ApiParam("是否覆盖（默认：否，此时如目标文件已经存在返回http 409 Conflict错误）") @RequestParam(value = "overwrite", defaultValue = "false") boolean overwrite) {
        if(file.isEmpty()) throw new BadRequestException("empty file");
        path = "/" + path;
        String ext = FilenameUtils.getExtension(file.getOriginalFilename());
        if(!path.toLowerCase().endsWith(ext.toLowerCase()))
            path += path.endsWith("/") ? file.getOriginalFilename() : "/" + file.getOriginalFilename();
        File destFile = new File(fileDirectory, path);
        if(destFile.exists())
            if(overwrite)
                destFile.delete();
            else
                throw new ConflictException("dest file exists");
        try {
            destFile.getParentFile().mkdirs();
            file.transferTo(Paths.get(destFile.getAbsolutePath()));
            return fileContextPath + path;
        } catch(IOException x) {
            log.warn(x.getMessage(), x);
            throw new InternalServerException(x);
        }
    }

    @ApiOperation("删除上传文件")
    @DeleteMapping(value = "/upload/{path}")
    @ResponseBody
    public boolean delete(@ApiParam("文件保存路径，包含文件名") @PathVariable("path") String path) {
        File destFile = new File(fileDirectory, "/" + path);
        return destFile.exists() && destFile.isFile() && destFile.delete();
    }

}
